/* @flow */

import {cached} from 'shared/util'
import {parseFilters} from './filter-parser'

const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g
const regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g

const buildRegex = cached(delimiters => {
  const open = delimiters[0].replace(regexEscapeRE, '\\$&')
  const close = delimiters[1].replace(regexEscapeRE, '\\$&')
  return new RegExp(open + '((?:.|\\n)+?)' + close, 'g')
})

type
TextParseResult = {
  expression: string,
  tokens: Array < string | {'@binding': string} >
}

export function parseText(
  text: string,
  delimiters

? : [string, string]
):
TextParseResult | void {
  const tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE
  if(
!tagRE.test(text)
)
{
  return
}
const tokens = []
const rawTokens = []
let lastIndex = tagRE.lastIndex = 0
let match, index, tokenValue
while ((match = tagRE.exec(text))) {
  index = match.index
  // push text token
  if (index > lastIndex) {
    rawTokens.push(tokenValue = text.slice(lastIndex, index))
    tokens.push(JSON.stringify(tokenValue))
  }
  // tag token
  const exp = parseFilters(match[1].trim())
  tokens.push(`_s(${exp})`)
  rawTokens.push({'@binding': exp})
  lastIndex = index + match[0].length
}
if (lastIndex < text.length) {
  rawTokens.push(tokenValue = text.slice(lastIndex))
  tokens.push(JSON.stringify(tokenValue))
}
return {
  expression: tokens.join('+'),
  tokens: rawTokens
}
}
